#pragma once

#include "gut/pch.h"
#include "gut/Vertex.h"
#include "gut/Mesh.h"

namespace Gut
{
	struct MeshVertexArrayDesc
	{
		void *vertexheader;
		unsigned int vertexStride;
		size_t vertexNum;

		const VertexLayout *layout;
		size_t numLayout;

		int faceType = GL_TRIANGLES;
		int usage = GL_STATIC_DRAW;

		template <typename V>
		bool CreateFrom(const std::vector<V> &vertices, const VertexLayout *layout, int numLayout,
						int faceType = GL_TRIANGLES, int usage = GL_STATIC_DRAW)
		{
			this->vertexheader = &vertices[0];
			this->vertexStride = sizeof(V);
			this->vertexNum = vertices.size();

			this->layout = layout;
			this->numLayout = numLayout;

			this->faceType = faceType;
			this->usage = usage;

			return true;
		}

		template <typename V>
		bool CreateFrom(const std::vector<V> &vertices,
						int faceType = GL_TRIANGLES, int usage = GL_STATIC_DRAW)
		{
			this->vertexheader = (void *)&vertices[0];
			this->vertexStride = sizeof(V);
			this->vertexNum = vertices.size();

			const auto &layout = V::inputLayout;
			this->layout = &layout[0];
			this->numLayout = layout.size();

			this->faceType = faceType;
			this->usage = usage;

			return true;
		}
	};


	struct MeshVertexArray : public Mesh
	{
		// vertex
		size_t vertexNum;
		unsigned int faceType = GL_TRIANGLES;

		bool CreateFromDesc(
			const MeshVertexArrayDesc &desc);
		template <typename VertexType>
		bool CreateFrom(
			const std::vector<VertexType> &vertices,
			int faceType = GL_TRIANGLES,
			int usage = GL_STATIC_DRAW)
		{
			return CreateFrom<VertexType>(vertices, VertexType::inputLayout, faceType, usage);
		}
		template <typename VertexType>
		bool CreateFrom(
			const std::vector<VertexType> &vertices,
			const std::vector<VertexLayout> &inputLayout,
			int faceType = GL_TRIANGLES,
			int usage = GL_STATIC_DRAW)
		{

			MeshVertexArrayDesc desc;

			desc.CreateFrom<VertexType>(vertices, faceType, usage);
			GUT_FAILED(CreateFromDesc(desc));
			this->faceType = faceType;

			return true;
		}
		void DrawArrays() const;
	};
}